# -*- coding:utf-8 -*-
# created on 2017/01/05
# __author__ = "XiaoHuang"

from mathsolver.functions.base import *
from mathsolver.functions.base.base import new_latex
from sympy import S, sympify
from mathsolver.functions.mathematica.mathematicaSolve import MathematicaSolve, MathematicaSimplify
from mathsolver.functions.xiangliang.basic import (XLJiHeConditionEqTransform, xl_search_multiple, XLJudgeAxis,
                                                   XLAxisConditionEqTransform)
from mathsolver.functions.xiangliang.Vector_Fundamental import vector_xiangs, vector_get_abs, vector_get_angles


# 坐标法：判断向量的位置关系: 不含equations
class VectorPosVector001(BaseFunction):
    """
    已知向量\\overrightarrow{a}=(-5,6),\\overrightarrow{b}=(6,5),则\\overrightarrow{a}与\\overrightarrow{b}()
    """
    def solver(self, *args):
        assert len(args) == 2
        if isinstance(args[0], BaseVector):
            vector_a = sympify(args[0].value)
        else:
            vector_a = args[0].sympify()
        if isinstance(args[1], BaseVector):
            vector_b = sympify(args[1].value)
        else:
            vector_b = args[1].sympify()
        known = self.known
        if 'Vequations' in known:
            veqs = known['Vequations']
            assert not veqs
        flag = XLJudgeAxis(known).solver(vector_a, vector_b).output[0].sympify()
        assert flag
        vector_a_axis_name = str('Axis_') + str(vector_a.args[0])
        vector_b_axis_name = str('Axis_') + str(vector_b.args[0])
        vector_a_value = self.search(vector_a_axis_name)
        vector_b_value = self.search(vector_b_axis_name)
        if len(vector_a_value) == 2 and len(vector_b_value) == 2:  # 平面向量
            a1, b1 = vector_a_value
            a2, b2 = vector_b_value
            tag1 = (a1 * b2 - a2 * b1).expand().simplify()
            tag2 = (a1 * a2 + b1 * b2).expand().simplify()
            if tag1 == 0:
                if ((a1 == 0) and (a2 == 0) and (b1 * b2 > 0)) or ((b1 == 0) and (b2 == 0) and (a1 * a2 > 0)):
                    self.steps.append(["", "%s 与 %s 平行且同向" % (new_latex(vector_a), new_latex(vector_b))])
                elif ((a1 == 0) and (a2 == 0) and (b1 * b2 < 0)) or ((b1 == 0) and (b2 == 0) and (a1 * a2 < 0)):
                    self.steps.append(["", "%s 与 %s 平行且反向" % (new_latex(vector_a), new_latex(vector_b))])
                elif ((a1 == 0) and (a2 == 0) and (b1 * b2 > 0)) or ((b1 == 0) and (b2 == 0) and (a1 * a2 > 0)):
                    self.steps.append(["", "%s 与 %s 平行且同向" % (new_latex(vector_a), new_latex(vector_b))])
                elif a1 * a2 > 0:
                    self.steps.append(["", "%s 与 %s 平行且同向" % (new_latex(vector_a), new_latex(vector_b))])
                else:
                    self.steps.append(["", "%s 与 %s 平行且反向" % (new_latex(vector_a), new_latex(vector_b))])
            elif tag2 == 0:
                self.steps.append(["", "∵ %s \\cdot %s = 0" % (new_latex(vector_a), new_latex(vector_b))])
                self.steps.append(["", "∴ %s 与 %s 垂直" % (new_latex(vector_a), new_latex(vector_b))])
            else:
                self.steps.append(["", "%s 与 %s 不垂直也不平行" % (new_latex(vector_a), new_latex(vector_b))])
            self.label.add("判断两平面向量的位置关系-坐标法")
        elif len(vector_a_value) == 3 and len(vector_b_value) == 3:  # 空间向量
            print(1)
        return self


# 坐标法：判断向量的位置关系: 含equations
class VectorPosVector002(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        if isinstance(args[0], BaseVector):
            vector_a = sympify(args[0].value)
        else:
            vector_a = args[0].sympify()
        if isinstance(args[1], BaseVector):
            vector_b = sympify(args[1].value)
        else:
            vector_b = args[1].sympify()
        known = self.known
        assert 'Vequations' in known
        veqs = known['Vequations']
        assert veqs
        flag = XLJudgeAxis(known).solver(vector_a, vector_b).output[0].sympify()
        assert flag
        vector_a_axis_name = str('Axis_') + str(vector_a.args[0])
        vector_b_axis_name = str('Axis_') + str(vector_b.args[0])
        vector_a_value = self.search(vector_a_axis_name)
        vector_b_value = self.search(vector_b_axis_name)
        if len(vector_a_value) == 2 and len(vector_b_value) == 2:  # 平面向量
            a1, b1 = vector_a_value
            a2, b2 = vector_b_value
            tag1 = (a1 * b2 - a2 * b1).expand().simplify()
            tag2 = (a1 * a2 + b1 * b2).expand().simplify()
            if tag1 == 0:
                if ((a1 == 0) and (a2 == 0) and (b1 * b2 > 0)) or ((b1 == 0) and (b2 == 0) and (a1 * a2 > 0)):
                    self.steps.append(["", "%s 与 %s 平行且同向" % (new_latex(vector_a), new_latex(vector_b))])
                elif ((a1 == 0) and (a2 == 0) and (b1 * b2 < 0)) or ((b1 == 0) and (b2 == 0) and (a1 * a2 < 0)):
                    self.steps.append(["", "%s 与 %s 平行且反向" % (new_latex(vector_a), new_latex(vector_b))])
                elif ((a1 == 0) and (a2 == 0) and (b1 * b2 > 0)) or ((b1 == 0) and (b2 == 0) and (a1 * a2 > 0)):
                    self.steps.append(["", "%s 与 %s 平行且同向" % (new_latex(vector_a), new_latex(vector_b))])
                elif a1 * a2 > 0:
                    self.steps.append(["", "%s 与 %s 平行且同向" % (new_latex(vector_a), new_latex(vector_b))])
                else:
                    self.steps.append(["", "%s 与 %s 平行且反向" % (new_latex(vector_a), new_latex(vector_b))])
            elif tag2 == 0:
                self.steps.append(["", "%s 与 %s 垂直" % (new_latex(vector_a), new_latex(vector_b))])
            else:
                self.steps.append(["", "%s 与 %s 不垂直也不平行" % (new_latex(vector_a), new_latex(vector_b))])
            self.label.add("判断两平面向量的位置关系-坐标法")
        elif len(vector_a_value) == 3 and len(vector_b_value) == 3:  # 空间向量
            print(1)
        return self


# 几何法：判断向量的位置关系: 含equations
class VectorPosVector004(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        if isinstance(args[0], BaseVector):
            vector_a = sympify(args[0].value)
        else:
            vector_a = args[0].sympify()
        if isinstance(args[1], BaseVector):
            vector_b = sympify(args[1].value)
        else:
            vector_b = args[1].sympify()
        assert 'Vequations' in self.known
        known = self.known
        veqs = known['Vequations']
        assert veqs
        flag = XLJudgeAxis(known).solver(vector_a, vector_b).output[0].sympify()
        assert not flag
        condition_eqs = []
        abs_symbols = []
        c_angle_symbols = []
        for eq in veqs:
            new_eq = XLJiHeConditionEqTransform(known).solver(BaseEq(eq)).output[0].sympify()
            expr = new_eq[0] - new_eq[1]
            if expr != 0:
                expr_abss = vector_get_abs(expr)
                if expr_abss:
                    for expr_Abs in expr_abss:
                        abs_symbols.append(expr_Abs)
                expr_c_angles = vector_get_angles(expr)
                if expr_c_angles:
                    for expr_CAngle in expr_c_angles:
                        c_angle_symbols.append(expr_CAngle)
                condition_eqs.append(new_eq)
        for index, eq in enumerate(condition_eqs):
            if len(eq) == 2:
                expr = eq[0] - eq[1]
            else:
                expr = eq[0] - eq[2]
            expr_vector_xiangs = vector_xiangs(expr)
            if expr_vector_xiangs:
                if len(eq) == 2:
                    new_eq = [eq[0] ** 2, eq[1] ** 2]
                else:
                    raise Exception("to do")
                new_eq = XLJiHeConditionEqTransform(known).solver(BaseEq(new_eq)).output[0].sympify()
                expr = new_eq[0] - new_eq[1]
                expr_abss = vector_get_abs(expr)
                if expr_abss:
                    for expr_Abs in expr_abss:
                        abs_symbols.append(expr_Abs)
                expr_c_angles = vector_get_angles(expr)
                if expr_c_angles:
                    for expr_CAngle in expr_c_angles:
                        c_angle_symbols.append(expr_CAngle)
                condition_eqs[index] = new_eq
            else:
                condition_eqs[index] = eq
        abs_symbols = set(abs_symbols)
        abs_symbols = list(abs_symbols)
        if abs_symbols:
            for Abs_symbol in abs_symbols:
                condition_eqs.append([Abs_symbol, '>=', S.Zero])
        c_angle_symbols = set(c_angle_symbols)
        c_angle_symbols = list(c_angle_symbols)
        if c_angle_symbols:
            for CAngle_symbol in c_angle_symbols:
                condition_eqs.append([CAngle_symbol, '>=', -1])
                condition_eqs.append([CAngle_symbol, '<=', 1])
        stepsolver = MathematicaSolve().solver(BaseIneqs(condition_eqs))
        solutions = stepsolver.output[0]
        assert solutions.sympify()
        chu_zhi_target = vector_a * vector_b
        chu_zhi_target = XLJiHeConditionEqTransform(known).solver(BaseEq([chu_zhi_target, S.Zero])).output[0].sympify()
        chu_zhi_target = chu_zhi_target[0]
        chu_zhi_answers = xl_search_multiple(solutions.sympify(), chu_zhi_target)
        chu_zhi_target_values = []
        for ans in chu_zhi_answers:
            new_value = chu_zhi_target
            new_value = new_value.subs(ans)
            new_value = MathematicaSimplify().solver(BasePoly(new_value)).output[0].sympify()
            chu_zhi_target_values.append(new_value)
        chu_zhi_target_values = set(chu_zhi_target_values)
        chu_zhi_target_values = list(chu_zhi_target_values)
        if len(chu_zhi_target_values) == 1 and chu_zhi_target_values[0] == 0:
            self.steps.append(["", "%s与%s垂直" % (new_latex(vector_a), new_latex(vector_b))])
            self.steps.append(["", "∴ %s * %s = 0" % (new_latex(vector_a), new_latex(vector_b))])
            veqs.append([vector_a * vector_b, S.Zero])
            self.output.append(BaseVectorValue({'Vequations': veqs}))
        self.label.add("判断两平面向量的位置关系-几何法")
        return self


# 判断两向量的位置关系
class VectorPosVector(BaseFunction):
    CLS = [VectorPosVector001, VectorPosVector002, VectorPosVector004]

    def solver(self, *args):
        known = self.known
        r = None
        for cl in VectorPosVector.CLS:
            try:
                new_known = dict(known)
                r = cl(new_known, verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r


# 根据向量垂直关系列方程
class XLChuiZhiEqs(BaseFunction):
    """
    设向量\\overrightarrow{a}=(x,x+1),\\overrightarrow{b}=(1,2),\\overrightarrow{a}⊥\\overrightarrow{b},则x=().
    """
    def solver(self, *args):
        vector1 = sympify(args[0].value)
        if isinstance(args[1], BaseVectorEq):
            vector2 = sympify(args[1].value[0])
        else:
            vector2 = sympify(args[1].value)
        self.steps.append(["", "由两平面向量垂直, 得"])
        self.steps.append(["", "(%s) %s (%s) = 0" % (new_latex(vector1), new_latex("\\cdot"), new_latex(vector2))])
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        veqs.append([vector1 * vector2, S.Zero])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        self.label.add("根据向量垂直关系列方程")
        return self


# 根据向量平行关系列方程
class XLPingXingEqs(BaseFunction):
    """
    已知向量\\overrightarrow{a}=(4,2),向量\\overrightarrow{b}=(x,3),\\overrightarrow{a}∥\\overrightarrow{b},则x=()
    """
    def solver(self, *args):
        if isinstance(args[0], BaseVectorEq):
            vector_a = sympify(args[0].value[0])
        else:
            vector_a = sympify(args[0].value)
        if isinstance(args[1], BaseVectorEq):
            vector_b = sympify(args[1].value[0])
        else:
            vector_b = sympify(args[1].value)
        self.steps.append(["", "由两平面向量平行, 得"])
        answer = {}
        if 'Vequations' in self.known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        g1 = sympify('g1')
        veqs.append([vector_a, g1 * vector_b])
        self.steps.append(["", "%s" % BaseEq([vector_a, g1 * vector_b]).printing()])
        answer['Vequations'] = veqs
        self.output.append(BaseVectorValue(answer))
        self.label.add("根据向量平行关系列方程")
        return self


# 向量垂直的充要条件
class XLChuiZhiChongYaoTiaoJian(BaseFunction):
    """
    已知向量\\overrightarrow a=(x-1,2),\\overrightarrow b =(2,1),则\\overrightarrow a ⊥\\overrightarrow b的充要条件是()
    """
    def solver(self, *args):
        if isinstance(args[0], BaseVectorEq):
            vector_a = sympify(args[0].value[0])
        else:
            vector_a = sympify(args[0].value)
        if isinstance(args[1], BaseVectorEq):
            vector_b = sympify(args[1].value[0])
        else:
            vector_b = sympify(args[1].value)
        known = self.known
        self.steps.append(["", "由两平面向量垂直, 得"])
        if 'Vequations' in known:
            veqs = self.search('Vequations')
        else:
            veqs = []
        veqs.append([vector_a * vector_b, S.Zero])
        known['Vequations'] = veqs
        flag = XLJudgeAxis(known).solver(vector_a, vector_b).output[0].sympify()
        condition_veqs = []
        if flag:
            for eq in veqs:
                if len(eq) == 3:
                    new_eqs = XLAxisConditionEqTransform(known).solver(BaseIneq(eq)).output[0].sympify()
                else:
                    new_eqs = XLAxisConditionEqTransform(known).solver(BaseEq(eq)).output[0].sympify()
                for new_eq in new_eqs:
                    condition_veqs.append(new_eq)
        else:
            print(1)
        self.steps.append(["", "依题意，得"])
        if len(condition_veqs) == 1:
            self.steps.append(["", "%s" % BaseEq(condition_veqs[0]).printing()])
        else:
            self.steps.append(["", "%s" % BaseIneqs(condition_veqs).printing()])
        solutions = MathematicaSolve().solver(BaseIneqs(condition_veqs)).output[0]
        self.steps.append(["", "解得: %s" % solutions.printing()])
        self.output.append(BaseSymbolValue(solutions.sympify()))
        return self
